package com.itheima.reggie.interceptor;

import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.R;
import com.itheima.reggie.constants.AttributeConstant;
import com.itheima.reggie.constants.CommonConstants;
import com.itheima.reggie.utils.LoginThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * 用户登录拦截器
 *
 * @author Upjqs
 * @since 2024-01-29 14:31
 */

@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 前置拦截
     *
     * @param request
     * @param response
     * @param handler
     * @return ture/false 放行/拦截
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 打印拦截路径
        log.info(">>>>>>>请求路径:{}", request.getRequestURI());

        // *******************多端情况******************

        // *********************员工端登录*********************
        Object empAttribute = request.getSession().getAttribute(AttributeConstant.ATTRIBUTE_EMPLOYEE);
        if (null != empAttribute) {
            // 员工id不为空
            Long employeeId = Long.valueOf(empAttribute.toString());
            log.info("-----------------当前员工{}已登录，请求放行......", employeeId);
            // 写入当前线程变量
            LoginThreadLocal.setCurrent(employeeId);
            // 并放行
            return true;
        }

        // *********************用户端登录*********************
        Object userAttribute = request.getSession().getAttribute(AttributeConstant.ATTRIBUTE_USER);
        if (null != userAttribute) {
            // 不为空
            Long userId = Long.valueOf(userAttribute.toString());
            log.info("-----------------当前用户{}已登录，请求放行......", userId);
            // 写入当前线程变量
            LoginThreadLocal.setCurrent(userId);
            // 并放行
            return true;
        }

        // redis认证
        String userId = stringRedisTemplate.opsForValue().get(CommonConstants.LOGIN_TOKEN.concat(AttributeConstant.ATTRIBUTE_USER));
        if (StringUtils.isNotBlank(userId)) {
            log.info("-----------------当前用户{}已登录，请求放行......", userId);
            // 写入当前线程变量
            LoginThreadLocal.setCurrent(Long.valueOf(userId));
            // 刷新过期时间
            stringRedisTemplate.expire(CommonConstants.LOGIN_TOKEN.concat(AttributeConstant.ATTRIBUTE_USER), 30, TimeUnit.MINUTES);
            // 并放行
            return true;
        }

        // 如果为空， 就抛出自定义异常，进行强制重新登录（全局异常处理器进行处理）
        log.info("-----------------当前未登录，请求被拦截， 抛出异常，强制重新登录......");
        // 设置响应信息
        //response.setStatus(555);

        //response.sendError(HttpEnum.UN_LOGIN.getCode(), HttpEnum.UN_LOGIN.getMsg());
        response.getWriter().write(
                // 将带有标识的R对象以JSON字符串写入响应中
                JSON.toJSONString(R.error("NOTLOGIN")));
        //response.setDateHeader("111",1110);
        // response.set
        // response.set
        // response.set
        //throw  new RuntimeException("NOTLOGIN");
        //拦截
        return false;
    }


    /**
     * 请求完成之后
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 请求完成清除用户变量
        LoginThreadLocal.remove();
    }
}
